﻿using System;
using System.IO;
using System.Media;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;


namespace 坐席端
{
    public partial class Form1 : Form
    {

        private static _Event Event = new _Event();
        private static ChromiumWebBrowser chromeBrowser;
        private static System.Diagnostics.Process p = new System.Diagnostics.Process()
        {
            StartInfo = {
                    FileName = "cmd.exe",
                    UseShellExecute = false,    //是否使⽤操作系统shell启动
                    RedirectStandardInput = true,//接受来⾃调⽤程序的输⼊信息
                    RedirectStandardOutput = true,//由调⽤程序获取输出信息
                    RedirectStandardError = true,//重定向标准错误输出
                    CreateNoWindow = true//不显⽰程序窗⼝
                }
        };

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            // this.FormBorderStyle = FormBorderStyle.None;     //设置窗体为无边框样式
            this.WindowState = FormWindowState.Maximized;    //最大化窗体 
            this.MaximizeBox = true; //最大化按键
            this.MinimizeBox = true;//取消最小化按键

            this.Text = GetConfig("title");

            // Initialize cef with the provided settings
            CefSettings settings = new CefSettings();
            settings.Locale = "zh-CN";
            //settings.CachePath = Application.StartupPath + "\\cache";
            settings.CefCommandLineArgs.Add("enable-media-stream", "1");  //开启摄像头
            settings.CefCommandLineArgs.Add("-enable-media-stream", "1");  //开启摄像头
            //settings.CefCommandLineArgs.Add("enable-system-flash", "1");  //flash
            settings.CefCommandLineArgs.Add("enable-speech-input", "1");  //语音输入
            settings.CefCommandLineArgs.Add("-enable-speech-input", "1");  //语音输入
            settings.CefCommandLineArgs.Add("--disable-web-security", "");  //跨域
            settings.LogSeverity = LogSeverity.Info;


            if (GetConfig("remoteDev") == "true")
            {
                settings.RemoteDebuggingPort = 46021;

                new Thread(
                    new ThreadStart(startFrp)
                    ).Start();
            }


            Cef.Initialize(settings);
            // Create a browser component
            chromeBrowser = new ChromiumWebBrowser(GetConfig("url"));
            // Add it to the form and fill it to the form window.
            this.Controls.Add(chromeBrowser);
            chromeBrowser.Dock = DockStyle.Fill;
            chromeBrowser.MenuHandler = new MenuHandler();
            chromeBrowser.KeyboardHandler = new CEFKeyBoardHander();
            //chromeBrowser.JavascriptObjectRepository.Register("api", new _Event(), isAsync: true, options: BindingOptions.DefaultBinder);
            chromeBrowser.JavascriptObjectRepository.ResolveObject += (s, eve) =>
            {
                var repo = eve.ObjectRepository;
                if (eve.ObjectName == "api")
                    repo.Register("api", Event, isAsync: true, options: BindingOptions.DefaultBinder);
            };


        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            string msg = GetConfig("closeMsg");
            if (msg != null && msg.Length != 0)
            {
                if (MessageBox.Show(msg, "关闭窗口", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
                {
                    e.Cancel = true;
                    return;
                }
            }
        }

        private static void startFrp()
        {
            p.Start();
            p.StandardInput.AutoFlush = true;
            Thread.Sleep(5000);
            p.StandardInput.WriteLine("taskkill /f /t /im frpc.exe");
            p.StandardInput.WriteLine("frpc.exe -c frpc.ini");
        }

        public static string GetConfig(String tagName)
        {
            FileStream fs = null;
            try
            {
                fs = new FileStream(System.Environment.CurrentDirectory + "\\config.ini", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader reader = new StreamReader(fs, System.Text.Encoding.Default);
                string line = null;
                while (((line = reader.ReadLine())) != null)
                {
                    // 判断是否是注释
                    if (line.StartsWith("#"))
                    {
                        continue;
                    }
                    string[] arr = line.Split('=');
                    if (arr == null || arr.Length == 0)
                    {
                        continue;
                    }
                    if (arr.Length == 2)
                    {
                        if (tagName.Equals(arr[0]))
                        {
                            return arr[1];
                        }
                    }
                    else if (arr.Length > 2)
                    {
                        if (tagName.Equals(arr[0]))
                        {
                            string value = "";
                            for (int i = 1; i < arr.Length; i++)
                            {
                                value += arr[i];
                                if (i != arr.Length - 1)
                                {
                                    value = value + "=";
                                }
                            }
                            return value;
                        }
                    }
                }

            }
            catch (Exception)
            { }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }

            }
            return null;
        }

        public class CEFKeyBoardHander : IKeyboardHandler
        {
            //https://bbs.csdn.net/topics/392375553
            public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
            {
                if (type == KeyType.KeyUp && Enum.IsDefined(typeof(Keys), windowsKeyCode))
                {
                    var key = (Keys)windowsKeyCode;
                    switch (key)
                    {
                        case Keys.F12:
                            browser.ShowDevTools();
                            break;

                        case Keys.F5:

                            if (modifiers == CefEventFlags.ControlDown)
                            {
                                //MessageBox.Show("ctrl+f5");
                                browser.Reload(true); //强制忽略缓存

                            }
                            else
                            {
                                //MessageBox.Show("f5");
                                browser.Reload();
                            }
                            break;
                        case Keys.R:
                            if (modifiers == CefEventFlags.ControlDown)
                            {
                                //MessageBox.Show("ctrl+R");
                                browser.Reload(); // 刷新

                            }
                            break;


                    }
                }
                return false;
            }

            public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
            {
                return false;
            }
        }

        private static FileStream LogFs = null;
        private static string LogPath = "";
        private static string LogLock = "";
        private static SoundPlayer sp = new SoundPlayer();


        public static void WriteLog(string str)
        {
            lock (LogLock)
            {
                // 写入日志
                try
                {
                    string logFilePath = Environment.CurrentDirectory + "\\log\\" + DateTime.Now.ToString("yyyyMMdd") + "-log.log";
                    // 如果当前日志不相同且流不为空 关闭当前流并创建新的流
                    if (!logFilePath.Equals(LogPath))
                    {
                        if (LogFs != null)
                        {
                            LogFs.Close();
                        }

                        if (!File.Exists(logFilePath))
                        {
                            // 日志文件不存在
                            LogFs = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                        }
                        else
                        {
                            // 日志文件存在
                            LogFs = new FileStream(logFilePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
                        }
                    }

                    //获得字节数组
                    byte[] data = Encoding.Default.GetBytes(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + ": " + str + "\n");
                    //开始写入
                    LogFs.Position = LogFs.Length;
                    LogFs.Write(data, 0, data.Length);
                    //清空缓冲区、关闭流
                    LogFs.Flush();
                }
                catch (IOException e)
                {
                }
            }
        }

        public static void playVoice(String name)
        {
            sp.SoundLocation = Environment.CurrentDirectory + "\\" + name;
            sp.Play();
        }

        public static void PlayVoiceLooping(String name)
        {
            sp.SoundLocation = Environment.CurrentDirectory + "\\" + name;
            sp.PlayLooping();
        }

        public static void StopVoice()
        {
            sp.Stop();
        }

        public class _Event
        {

            public void act(string action, string str)
            {
                switch (action)
                {
                    case "WriteLog":
                        WriteLog(str);
                        break;
                    case "playVoice":
                        playVoice(str);
                        break;
                    case "PlayVoiceLooping":
                        PlayVoiceLooping(str);
                        break;
                    case "StopVoice":
                        StopVoice();
                        break;
                }
            }


        }

        internal class MenuHandler : IContextMenuHandler
        {
            public bool OnBeforeContextMenu(IWebBrowser browser, IBrowser ibrower, IFrame iframe, IContextMenuParams icontextmenuparams, IMenuModel imenumodel)
            {
                return false;
            }

            public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
            {
                return false;
            }

            public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
            {
            }

            public bool RunContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
            {
                return true;
            }

            void IContextMenuHandler.OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
            {
                model.Clear();
            }
        }
    }
}